# 植物路由
import os
import shutil
from pathlib import Path

from exts import db
from flask import request, jsonify, g
from models import Plant, Dataset, Model, Predict


def register_plant_routes(app):
    # 查询所有植物
    @app.route('/plantACR/getPlants', methods=['GET'])
    def get_plants():
        # 定义 resultVO，包含code和data的字典，用于存储响应信息
        resultVO = {
            "code": 200,
            "data": {
                "plants": []
            }
        }
        try:
            # 按id升序排序
            plants_asc = Plant.query.order_by(Plant.id.asc()).all()
            if plants_asc:
                for plant in plants_asc:
                    plant_info = {
                        "id": plant.id,
                        "name": plant.name,
                        "description": plant.description,
                        "picture": plant.picture,
                        "dataset_count": Dataset.query.filter_by(plant_id=plant.id).count(),
                        "model_count": Model.query.filter_by(plant_id=plant.id).count(),
                        "predict_count": Predict.query.filter_by(plant_id=plant.id).count()
                    }
                    resultVO["data"]["plants"].append(plant_info)
                return jsonify(resultVO)
            else:
                # 不需要设定code为404，因为表空，那么前端只需要渲染空的表格即可
                # resultVO["code"] = 404
                resultVO["message"] = '植物列表为空'
                return jsonify(resultVO)
        except Exception as e:
            resultVO["code"] = 500
            resultVO["message"] = "服务器错误，获取植物列表失败！" + str(e)
            return jsonify(resultVO)

    # 创建植物
    @app.route('/plantACR/createPlant', methods=['POST'])
    def create_plant():
        # 定义 resultVO，包含code和data的字典，用于存储响应信息
        resultVO = {
            "code": 200,
            "data": {}
        }
        try:
            data = request.get_json()
            name = data.get('name')
            fa_name = data.get('fa')

            # 检查植物名是否已存在
            existing_plant = Plant.query.filter_by(name=name).first()
            if existing_plant:
                resultVO["code"] = 400
                resultVO["message"] = '植物名已存在'
                return jsonify(resultVO)

            # 创建新植物
            new_plant = Plant(name=name, description=data.get('description'), picture=data.get('picture'))
            db.session.add(new_plant)
            db.session.commit()

            # 创建新植物名字的基因组文件夹
            plant_fasta_dir = Path(app.root_path) / "ACRmodel" / "static" / "fasta"
            plant_fasta_dir.mkdir(parents=True, exist_ok=True)
            # 创建新植物名字的数据集文件夹
            plant_dataset_dir = Path(app.root_path) / "ACRmodel" / "static" / "dataset"
            plant_dataset_dir.mkdir(parents=True, exist_ok=True)
            # 创建新植物名字的模型文件夹
            plant_model_dir = Path(app.root_path) / "ACRmodel" / "static" / "weights"
            plant_model_dir.mkdir(parents=True, exist_ok=True)
            # 创建新植物名字的预测预处理结果文件夹
            plant_predict1_dir = Path(app.root_path) / "ACRmodel" / "static" / "predict_data"
            plant_predict1_dir.mkdir(parents=True, exist_ok=True)
            # 创建新植物名字的预测结果文件夹
            plant_predict2_dir = Path(app.root_path) / "ACRmodel" / "static" / "predict_result"
            plant_predict2_dir.mkdir(parents=True, exist_ok=True)

            if fa_name and fa_name.strip():
                # 移动基因组文件
                source_file = Path(app.root_path) / "ACRmodel" / "static" / "temp" / fa_name  # 源文件路径
                destination_file = plant_fasta_dir / f"{name}.fa"  # 目标文件路径
                if source_file.exists():
                    shutil.move(str(source_file), str(destination_file)) # 移动文件
                    print(f"文件已从 {source_file} 移动到 {destination_file}")

            resultVO["message"] = '植物创建成功'
            # 刚刚创建的植物信息
            resultVO["data"] = {
                "plant": {
                    "id": new_plant.id,
                    "name": new_plant.name,
                    "description": new_plant.description,
                    "picture": new_plant.picture
                }
            }
            return jsonify(resultVO)
        except Exception as e:
            db.session.rollback()
            # 处理异常，返回500错误
            print("错误：", str(e))
            resultVO["code"] = 500
            resultVO["message"] = "服务器错误，植物创建失败！"
            return jsonify(resultVO)

    # 更新植物
    @app.route('/plantACR/updatePlant', methods=['POST'])
    def update_plant():
        # 定义 resultVO，包含code和data的字典，用于存储响应信息
        resultVO = {
            "code": 200,
            "data": {}
        }
        try:
            data = request.get_json()
            plant_id = data.get('id')
            new_name = data.get('name')

            # 检查新植物名是否已存在
            existing_plant = Plant.query.filter_by(name=new_name).first()
            if existing_plant and existing_plant.id != plant_id:
                resultVO["code"] = 400
                resultVO["message"] = '要更改的植物名已存在'
                return jsonify(resultVO)

            plant = Plant.query.get(plant_id)

            if plant:
                # 更新信息，如果请求中没有提供某个字段的值，则使用植物当前的值
                old_name = plant.name  # 保存旧名称用于文件重命名
                fasta_dir = Path(app.root_path) / "ACRmodel" / "static" / "fasta"
                old_file = fasta_dir / f"{old_name}.fa"
                new_file = fasta_dir / f"{new_name}.fa"
                if old_file.exists():
                    os.rename(str(old_file), str(new_file))
                plant.name = data.get('name', plant.name)
                plant.description = data.get('description', plant.description)
                plant.picture = data.get('picture', plant.picture)
                db.session.commit()

                # 与植物关联的所有数据集的plant_name字段更新为新的plant_name
                datasets = Dataset.query.filter_by(plant_id=plant_id).all()
                if datasets:
                    for dataset in datasets:
                        dataset.plant_name = plant.name
                        db.session.commit()

                # 与植物关联的所有模型的plant_name字段更新为新的plant_name
                models = Model.query.filter_by(plant_id=plant_id).all()
                if models:
                    for model in models:
                        model.plant_name = plant.name
                        db.session.commit()

                # 与植物关联的所有预测记录的plant_name字段更新为新的plant_name
                predicts = Predict.query.filter_by(plant_id=plant_id).all()
                if predicts:
                    for predict in predicts:
                        predict.plant_name = plant.name
                        db.session.commit()

                resultVO["data"] = {
                    "plant": {
                        "id": plant.id,
                        "name": plant.name,
                        "description": plant.description,
                        "picture": plant.picture
                    }
                }
                resultVO["message"] = '植物信息更新成功'
                return jsonify(resultVO)
            else:
                resultVO["code"] = 404
                resultVO["message"] = '植物不存在'
                return jsonify(resultVO)
        except Exception as e:
            db.session.rollback()
            print(e)
            resultVO["code"] = 500
            resultVO["message"] = "服务器错误，植物更新失败！"
            return jsonify(resultVO)

    # 删除植物
    @app.route('/plantACR/deletePlant', methods=['POST'])
    def delete_plant():
        resultVO = {
            "code": 200,
            "data": {}
        }
        try:
            current_plant_role = g.role

            data = request.get_json()
            plant_id = data.get('id')

            # 检查权限，只有管理员能删除植物
            if current_plant_role != 'admin':
                resultVO["code"] = 403
                resultVO["message"] = '权限不足！'
                return jsonify(resultVO)

            # 检查植物是否存在数据集
            plant_datasets = Dataset.query.filter_by(plant_id=plant_id).first()
            if plant_datasets:
                resultVO["code"] = 400
                resultVO["message"] = '该植物存在数据集，无法删除'
                return jsonify(resultVO)

            # 检查植物是否存在模型
            plant_models = Model.query.filter_by(plant_id=plant_id).first()
            if plant_models:
                resultVO["code"] = 400
                resultVO["message"] = '该植物存在模型，无法删除'
                return jsonify(resultVO)

            # 检查植物是否存在预测记录
            plant_predicts = Predict.query.filter_by(plant_id=plant_id).first()
            if plant_predicts:
                resultVO["code"] = 400
                resultVO["message"] = '该植物存在预测记录，无法删除'
                return jsonify(resultVO)

            plant = Plant.query.get(plant_id)
            if plant:
                db.session.delete(plant)
                db.session.commit()
                resultVO["data"] = {
                    "plant": {
                        "id": plant.id,
                        "name": plant.name
                    }
                }
                resultVO["message"] = '植物删除成功'
                return jsonify(resultVO)
            else:
                resultVO["code"] = 404
                resultVO["message"] = '植物不存在'
                return jsonify(resultVO)
        except Exception as e:
            db.session.rollback()
            print(e)
            resultVO["code"] = 500
            resultVO["message"] = "服务器错误，植物删除失败！"
            return jsonify(resultVO)

    return app
